/********************** (C) COPYRIGHT 2007-2010 RAISONANCE ********************
*
* File Name          :  Application.c
* Description        :  Circle_App CircleOS application template.
*
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include "Application.h"
#include "circle_api.h"
#include "ClockCounter.h"
#include "Number.h"
#include "DSP.h"
#include "Sound.h"
#include "WavFile.h"

/* Private defines -----------------------------------------------------------*/

// The following should be the minimal CircleOS version needed by your application
#define NEEDEDVERSION "V 4.0"

/* Private functions ---------------------------------------------------------*/
static enum MENU_code MsgVersion(void);

/* Public variables ----------------------------------------------------------*/
const char Application_Name[8+1] = {"PSound 1"};      // Max 8 characters
PLAYER_State State;
uint8_t CurrentPath[MAX_PATH_LENGTH];
FILEINFO file_info;
u32 StartMBR;
VOLINFO volume_info;
uint8_t AudioFileHeader[HEADER_SIZE];


/*******************************************************************************
* Function Name  : Application_Ini
* Description    : Initialization function of Circle_App. This function will
*                  be called only once by CircleOS.
* Input          : None
* Return         : MENU_CONTINUE_COMMAND
*******************************************************************************/
enum MENU_code Application_Ini(void) {
    s16 *ab;
    // Ensure that the current OS version is recent enough
    if(strcmp(UTIL_GetVersion(), NEEDEDVERSION) < 0) {
        return MsgVersion();
    }
    LCD_SetOffset(OFFSET_OFF);

#if 1
    DRAW_DisplayStringWithMode( 0, 200, Application_Name, ALL_SCREEN, NORMAL_TEXT, CENTER);
#endif


    // Your can set the frequency of the call by the system.
    UTIL_SetPll(SPEED_VERY_HIGH);
    MENU_SetAppliDivider(1); // (100 = 33.33 ms handler frequency, 50=16.67ms)
    CycleCounter_Init();
    
    State = StateExploring;
    FS_Explorer_Ini();

    Sound_Init();
    AUDIO_SetMode(AUDIO_CIRCULAR_MODE, LG_16_BITS, FRQ_44KHZ, STEREO);
    AUDIO_Play(Sound_Get_AudioBuffer(), SOUND_BUFFER_LENGTH);

    return MENU_CONTINUE_COMMAND;
 }

/*******************************************************************************
* Function Name  : Application_Handler
* Description    : Management of the Circle_App. This function will be called
*                  every millisecond by CircleOS while it returns MENU_CONTINUE.
* Input          : None
* Return         : MENU_CONTINUE
*******************************************************************************/
enum MENU_code Application_Handler(void) {

    if ( State == StateExploring )
        {
        switch ( FS_Explorer ( ) )
            {
            case -1: //continue;
                return MENU_CONTINUE;   // Returning MENU_LEAVE will quit to CircleOS

            case 0:  //quit
                return MENU_Quit();

            case +1: //selection done
                State = StateRun;
                strcpy ( CurrentPath, (u8*) FS_GetSDCardCurrentPath() );
                DRAW_Clear();
                DRAW_SetBGndColor(RGB_WHITE);
                DRAW_SetTextColor(RGB_BLACK);
                DRAW_Puts( "\nFile to play:\n  " );
                DRAW_SetTextColor(RGB_BLUE);
                DRAW_Puts( CurrentPath );

                // mount MMCSD 
                StartMBR=FS_Mount(MMCSD_SDIO);
                if (StartMBR == 0xFFFFFFFF)
                    {
                    DRAW_Puts("\n No SDCARD");
                    return -1;
                    }

                // Open volume on first partition (0)
                if (FS_GetVolumeInfo(0, StartMBR, &volume_info))
                    {
                    DRAW_Puts("\nErr: GetVolInfo");
                    return -1;
                    }

                //Open selected file
                if (FS_OpenFile(&volume_info, CurrentPath,FS_READ, &file_info))
                    {
                    DRAW_Puts("\n Err op: File");
                    return MENU_Quit();
                    }
                
                strupr(CurrentPath);
                if ( strstr(CurrentPath, "WAV") )
                    {
                    u32 i ; 

                    //wav file, to be parsed
                    DRAW_Puts("\n*Parse wav*");
                    FS_ReadFile(&file_info, (u8 *)AudioFileHeader, &i, HEADER_SIZE);
                    if ( i == HEADER_SIZE )
                        {
                        ErrorCode ret = WavFile_CODEC_Parsing( (u8*) AudioFileHeader);
                        
                        if ( ret == Valid_WAVE_File )
                            {
                            }
                        }                     
                    }
                break;                
            }
        }
    else //StatePlaying
        {
        if ( BUTTON_GetState() == BUTTON_PUSHED )
            {
            DRAW_Clear();
            BUTTON_WaitForRelease();
            AUDIO_Playback_Stop();
            return MENU_Quit();
            }
        return Sound_FillBuffer(&file_info);
        }
    return MENU_CONTINUE;   // Returning MENU_LEAVE will quit to CircleOS    
 }

/*******************************************************************************
* Function Name  : MsgVersion
* Description    : Displays the current CircleOS version and the version needed
*                  exit to main menu after 4 seconds
* Input          : None
* Return         : MENU_REFRESH
*******************************************************************************/
static enum MENU_code MsgVersion(void) {
    u8 hh, mm, ss, ss2;

    DRAW_DisplayString( 5,  60, "CircleOS", 17 );
    DRAW_DisplayString( 80, 60, UTIL_GetVersion(), 6 );
    DRAW_DisplayString( 5,  34, NEEDEDVERSION, 6 );
    DRAW_DisplayString( 50, 34, " required", 12 );

    RTC_GetTime( &hh, &mm, &ss );
    ss = ss + 4;
    ss = ss % 60;

    do {
        RTC_GetTime( &hh, &mm, &ss2 );
    } while ( ss2 != ss );           // do while < 4 seconds

    DRAW_Clear();
    return MENU_REFRESH;
}
